import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:get/get.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:ichinesereader/constants.dart';
import 'package:ichinesereader/controller/cache.dart';
import 'package:ichinesereader/utils/helper.dart';
import 'package:syncfusion_flutter_gauges/gauges.dart';
import 'package:ichinesereader/utils/log.dart';
import '../../themes/appTheme.dart';

class LevelGaugeChart extends StatefulWidget {
  @override
  _LevelGaugeChartState createState() => _LevelGaugeChartState();
}

class _LevelGaugeChartState extends State<LevelGaugeChart> {
  _LevelGaugeChartState();

  final box = Hive.box('appconfig');
  bool isWebOrDesktop = GetPlatform.isMacOS || GetPlatform.isWeb;
  List<GaugeRange> levelGauges = [];
  double _currentValue = 1.0;

  //String _annotationValue = '';
  //double _markvalue = 1.0;
  late Color _rangecolor;

  @override
  void initState() {
    try {
      bool isStudentIndividual =
          box.get(CacheManagerKey['nanhairole'].toString()) ==
                  Constants.NanhaiRole_Student ||
              box.get(CacheManagerKey['nanhairole'].toString()) ==
                  Constants.NanhaiRole_Individual;
      if (isStudentIndividual) {
        var level = box.get('UserLevel').toString().replaceAll('level', '');
        _currentValue = double.tryParse(level) ?? 1;
      } else {
        _currentValue = double.tryParse(
            box.get(CacheManagerKey['eveluationlevel'].toString()).toString()) ?? 1;
      }
    } catch (error) {
      Log.debug(error.toString());
      _currentValue = 1.0;
    }

    _rangecolor = hexStringToHexInt(Constants.bookLevelColors
        .where((element) => element.level == _currentValue.toInt())
        .first
        .color
        .toString());
    _buildLevelGauges('ACTFL');
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Padding(
          padding: const EdgeInsets.only(top: 18.0),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(
                  height: 48,
                  width: 150,
                  child: FormBuilderChoiceChip(
                    decoration: InputDecoration.collapsed(
                      hintText: '',
                      border: InputBorder.none,
                    ),
                    spacing: 8,
                    labelStyle: TextStyle(
                      color: Get.isDarkMode
                          ? Colors.black
                          : Theme.of(context).primaryColorLight,
                      fontSize: 15,
                      letterSpacing: 0.8,
                    ),
                    backgroundColor: Get.isDarkMode
                        ? Get.theme.primaryColor
                        : Colors.blueGrey,
                    selectedColor: Get.isDarkMode
                        ? (Colors.white)
                        : Theme.of(context).primaryColorDark,
                    name: 'level_standard_types',
                    onChanged: (value) {
                      if (value == null) return;
                      _buildLevelGauges(value.toString());
                      setState(() {
                        try {
                          _currentValue = double.parse(box
                              .get(
                                  CacheManagerKey['eveluationlevel'].toString())
                              .toString());
                        } catch (error) {
                          _currentValue = 1.0;
                          Log.debug(error);
                        }
                        //_markvalue = _currentValue;
                      });
                    },
                    initialValue: Constants.levelStandardTypes[1],

                    ///这里暂时去掉yct
                    options: Constants.levelStandardTypes
                        .where(
                            (element) => element != 'YCT' && element != 'ICR')
                        .map((state) => FormBuilderChipOption<String>(
                              value: state,
                              child: Text(
                                state.toString(),
                              ),
                            ))
                        .toList(),
                  )),
            ],
          ),
        ),
        Expanded(
          child: _buildRangeColorForLabels(),
        ),
      ],
    );
  }

  _buildLevelGauges(String type) {
    levelGauges = [];
    var iLevel = 0;
    if (type == 'ACTFL') iLevel = 0;
    if (type == 'HSK') iLevel = 1;
    if (type == 'YCT') iLevel = 2;
    var categories =
        Constants.levelAxisCategories.where((x) => x.level == iLevel).toList();
    categories.forEach((item) {
      var rangecolor;
      if (iLevel == 0)
        rangecolor = Constants.bookLevelColors
            .where((element) => element.actflLevel == item.text)
            .first
            .actflColor;
      if (iLevel == 1)
        rangecolor = Constants.bookLevelColors
            .where((element) => element.hskLevel == item.text)
            .first
            .hskColor;
      if (iLevel == 2)
        rangecolor = Constants.bookLevelColors
            .where((element) => element.yctLevel == item.text)
            .first
            .yctColor;

      double endvalue = double.parse(item.end.toString());

      var range = GaugeRange(
        startValue: double.parse(item.start.toString()) - 1,
        endValue: endvalue,
        label: item.text,
        color: rangecolor,
        sizeUnit: GaugeSizeUnit.factor,
        rangeOffset: 0.06,
        startWidth: isWebOrDesktop ? 0.2 : 0.1,
        endWidth: isWebOrDesktop ? 0.2 : 0.1,
      );
      levelGauges.add(range);
    });
  }

  Container _buildRangeColorForLabels() {
    return Container(
      margin: EdgeInsets.all(60.0),
      decoration: BoxDecoration(
        shape: BoxShape.circle,
        color: Get.isDarkMode
            ? AppTheme.colors.darkTheme2
            : Colors.white.withOpacity(0.3),
        boxShadow: [
          BoxShadow(
            blurRadius: 30,
            spreadRadius: 1,
            color: Get.isDarkMode
                ? Colors.transparent
                : Colors.black.withOpacity(0.1),
            offset: Offset(1, 1),
          ),
        ],
      ),
      child: SfRadialGauge(
        animationDuration: 2500,
        enableLoadingAnimation: true,
        axes: <RadialAxis>[
          RadialAxis(
            ticksPosition: ElementsPosition.outside,
            labelsPosition: ElementsPosition.outside,
            minimum: 0,
            maximum: 20,
            useRangeColorForAxis: false,
            interval: 1,
            showFirstLabel: false,
            showLastLabel: true,
            axisLineStyle: const AxisLineStyle(
              thickness: 10,
            ),
            axisLabelStyle: const GaugeTextStyle(fontWeight: FontWeight.w500),
            majorTickStyle: const MajorTickStyle(
                length: 0.05, lengthUnit: GaugeSizeUnit.factor, thickness: 1),
            minorTicksPerInterval: 0,
            minorTickStyle: const MinorTickStyle(
                length: 0.04, lengthUnit: GaugeSizeUnit.factor, thickness: 1),
            ranges: levelGauges,
            annotations: <GaugeAnnotation>[
              GaugeAnnotation(
                  widget: Row(
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      Text(
                        'Current Level: ${_currentValue.toInt()}',
                        style: TextStyle(
                            fontSize: 18.0,
                            fontFamily: 'Montserrat',
                            color: Get.theme.primaryColorLight),
                      )
                    ],
                  ),
                  positionFactor: 0.13,
                  angle: 0)
            ],
            pointers: <GaugePointer>[
              RangePointer(
                  value: _currentValue,
                  color: _rangecolor,
                  onValueChanged: handlePointerValueChanged,
                  onValueChangeEnd: handlePointerValueChanged,
                  onValueChanging: handlePointerValueChanging,
                  enableDragging: true,
                  width: 0.03,
                  sizeUnit: GaugeSizeUnit.factor),
              // MarkerPointer(
              //   value: _currentValue,
              //   color: _rangecolor,
              //   markerHeight: _firstMarkerSize,
              //   markerWidth: _firstMarkerSize,
              //   markerType: MarkerType.circle,
              // ),
            ],
          ),
        ],
      ),
    );
  }

  /// Dragged pointer new value is updated to pointer and
  /// annotation current value.
  void handlePointerValueChanged(double value) {
    if (value.toInt() >= 1) {
      setState(() {
        _currentValue = value.roundToDouble();
        final int currentValue = _currentValue.toInt();
        //_annotationValue = '$currentValue';
        //_markvalue = _currentValue;
        //Log.debug('level chart marker value: $_markvalue');
        _rangecolor = hexStringToHexInt(Constants.bookLevelColors
            .where((element) => element.level == currentValue)
            .first
            .color
            .toString());
        box.put(CacheManagerKey['eveluationlevel'].toString(), _currentValue);
      });
    }
  }

  /// Pointer dragging is canceled when dragging pointer value is less than 6.
  void handlePointerValueChanging(ValueChangingArgs args) {
    if (args.value.toInt() < 0.8) {
      args.cancel = true;
    }
  }
}
